<template>
    <el-popover v-model="data.isPopoverVisible" :disabled="disabled" placement="bottom-start" width="400">
        <div style="max-height: 500px; overflow: auto">
            <el-tree v-if="multiple" node-key="key" ref="treeRef" :props="treeProps" :load="loadNode" lazy show-checkbox
                     @check="multipleChecked">
            </el-tree>
            <el-tree v-else node-key="key" ref="treeRef" :props="treeProps" :load="loadNode" lazy
                     @current-change="singleChecked">
            </el-tree>
        </div>
        <el-input slot="reference" :value="data.displayValue" :disabled="disabled"
                  :placeholder="multiple ? '请选择项目/分期/楼栋/单元/房屋' : '请选择房屋'" readonly ref="inputRef"></el-input>
    </el-popover>
</template>

<script setup lang="ts">
import { onMounted, reactive, watch, ref } from "vue";
import { TreeProps, TreeData, TreeNode } from 'element-ui/types/tree';
import request from 'src/utils/request';
import store from '../../store';
import { type ElInput } from "element-ui/types/input";


export interface HouseSelector {
    village: string[],
    stages: string[],
    building: string[],
    unit: string[],
    room: string[]
}

const props = defineProps<{
    value?: HouseSelector | string | number,
    multiple?: boolean,
    disabled?: boolean
}>()

const emit = defineEmits<{
    (event: 'input', value: HouseSelector | string | number | null): void
}>()

const inputRef = ref<ElInput>()
const treeRef = ref()
const treeProps = reactive<TreeProps>({
    label: 'name',
    disabled: 'isDisabled',
    isLeaf: 'isLeaf',
    children: 'children'
})

const data = reactive({
    isPopoverVisible: false,
    displayValue: ''
})

let currentRequestId = 0
onMounted(() => {
    updateDisplayValue()
    restoreTreeState()
})
watch(() => props.value, async (value, oldValue) => {
    if (value !== oldValue) {
        updateDisplayValue()
        restoreTreeState()
    }
})

function restoreTreeState() {
    // 赋值给 tree 
    const value = props.value
    let ids: any[] = [];
    if (value) {
        if (typeof value === 'string' || typeof value === 'number') {

        } else {
            ids.push(...value['village'].map(id => 'village:' + id))
            ids.push(...value['stages'].map(id => 'stages:' + id))
            ids.push(...value['building'].map(id => 'building:' + id))
            ids.push(...value['unit'].map(id => 'unit:' + id))
            ids.push(...value['room'].map(id => 'room:' + id))
        }
    }
    treeRef.value.setCheckedKeys(ids);
}

async function updateDisplayValue() {
    const value = props.value
    if (!value) {
        data.displayValue = ''
        return
    }
    if (!props.multiple) {
        const requestId = currentRequestId + 1
        currentRequestId = requestId
        const result = await request(`/resource/room/queryRoomByRoomId/${value}`)
        if (requestId === currentRequestId && result.success && result.data.address) {
            data.displayValue = result.data.address
        }
    } else {
        data.displayValue = '已选择'

        if (value.village.length) {
            data.displayValue += value.village.length + '个项目；'
        }
        if (value.stages.length) {
            data.displayValue += value.stages.length + '个分期；'
        }
        if (value.building.length) {
            data.displayValue += value.building.length + '栋楼；'
        }
        if (value.unit.length) {
            data.displayValue += value.unit.length + '个单元；'
        }
        if (value.room.length) {
            data.displayValue += value.room.length + '间房屋；'
        }
    }
}

async function loadNode(node: TreeNode<string, TreeData>, resolve: Function) {
    const id = node.data?.id
    const type = ['village', 'stages', 'building', 'unit', 'room'][node.level]
    const result = await queryTreeNodes({ id, type })
    resolve(result)
}

function getCheckedNodes() {
    const root = treeRef.value.root as TreeNode<string, TreeData>
    root.indeterminate = true
    function getCheckedNodes(node: TreeNode<string, TreeData>): TreeData[] {
        if (node.checked) {
            return [node.data]
        } else if (node.indeterminate) {
            return node.childNodes.flatMap(getCheckedNodes)
        } else {
            return []
        }
    }
    return getCheckedNodes(root)
}

function multipleChecked() {
    const checkeds = getCheckedNodes()
    const input = {
        village: [],
        stages: [],
        building: [],
        unit: [],
        room: []
    }
    checkeds.forEach(node => input[node.type].push(node.id))
    data.displayValue = '已选择'
    if (input.village.length) {
        data.displayValue += input.village.length + '个项目；'
    }
    if (input.stages.length) {
        data.displayValue += input.stages.length + '个分期；'
    }
    if (input.building.length) {
        data.displayValue += input.building.length + '栋楼；'
    }
    if (input.unit.length) {
        data.displayValue += input.unit.length + '个单元；'
    }
    if (input.room.length) {
        data.displayValue += input.room.length + '间房屋；'
    }
    emit('input', input)
    inputRef.value!.focus()
    inputRef.value!.blur()
}
function singleChecked(nodeData: any, node: any) {
    console.log(arguments)
    const nameOf = (node: any): string => {
        if (node.parent && node.parent.data) {
            return `${nameOf(node.parent)}${node.data.name}`
        } else {
            return node.data.name
        }
    }

    if (nodeData.type === 'room') {
        emit('input', nodeData.id)
        inputRef.value!.focus()
        inputRef.value!.blur()
        data.isPopoverVisible = false
        data.displayValue = nameOf(node)
    }
}

function setValue(value: HouseSelector | string) {
    if (typeof value === 'string') {
        if (props.multiple) {
            emit('input', null)
        } else {

        }
    } else {
        if (props.multiple) {

        } else {

        }
    }
}
function reset() {
    treeRef.value.setCheckedKeys([])
    data.displayValue = ''
    emit('input', null)
}

async function queryTreeNodes(params: { id?: string, type: string }) {
    const orgId = store.getters.vid ?? ''
    const result = await request({
        url: '/resource/info/tree',
        method: 'post',
        data: {
            orgId,
            ...params
        }
    })
    // 根据name排序
    if(params.type != 'village'){
        result.data.sort((a,b)=>{
            const numa = parseFloat(a.name)
            const numb = parseFloat(b.name)
            if (isNaN(numa) || isNaN(numb)) {
                return a.name.localeCompare(b.name)
            }else {
                return numa - numb
            }
        })
    }

    const meansure = {
        village: '',
        stages: '期',
        building: '栋',
        unit: '单元',
        room: '室'
    }[params.type]

    result.data.forEach(d => {
        d.isLeaf = !d.childType
        d.name += meansure
        d.key = params.type + ':' + d.id
    })

    return result.data
}

defineExpose({
    reset,setValue
})
</script>

<style scoped>
</style>